package edu.hawaii.duedates;

import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.CommandLineParser;
import org.apache.commons.cli.MissingArgumentException;
import org.apache.commons.cli.Option;
import org.apache.commons.cli.Options;
import org.apache.commons.cli.ParseException;
import org.apache.commons.cli.PosixParser;
import org.apache.commons.cli.UnrecognizedOptionException;

/**
 * Command Line class designed to take in arguments.
 * 
 * @author Ka Hung Phillip Lau
 * @author Creighton Okada
 * 
 */
public class CommandLineArguments {
  /**
   * Console option.
   */
  public static final String CONSOLE = "console";
  /**
   * Hawai'i State Library option.
   */
  public static final String HSL = "hsl";
  /**
   * University of Hawai'i at Manoa option.
   */
  public static final String UHM = "uhm";
  /**
   * Argument 'within' option.
   */
  public static final String WITHIN = "within";
  /**
   * Argument 'wakeup' option.
   */
  public static final String WAKEUP = "wakeup";
  /**
   * Argument 'email' option.
   */
  public static final String EMAIL = "email";
  /**
   * Command Line object.
   */
  private CommandLine commandLine = null;
  /**
   * Options object.
   */
  private final Options options = new Options();

  /**
   * Parses arguments given.
   * 
   * @param args given arguments
   * @throws ParseException thrown if error occurs in command line parsing
   */
  public void parseArgs(String[] args) throws ParseException {
    try {
      CommandLineParser parser = new PosixParser();

      Option console = new Option(CONSOLE, false, "Console");
      options.addOption(console);
      
      Option uhm = new Option(UHM, false, "UH Stuff");
      uhm.setArgs(2);
      uhm.setArgName("ID/LastName");
      options.addOption(uhm);

      Option hsl = new Option(HSL, false, "HSL stuff");
      hsl.setArgs(2);
      hsl.setArgName("barcode/pin");
      options.addOption(hsl);

      Option within = new Option(WITHIN, false, "Within stuff");
      within.setArgs(1);
      within.setArgName("dayinterval");
      options.addOption(within);

      Option wakeup = new Option(WAKEUP, false, "Wakeup stuff");
      wakeup.setArgs(1);
      wakeup.setArgName("timeinterval");
      options.addOption(wakeup);

      Option email = new Option(EMAIL, false, "Email stuff");
      email.setArgs(2);
      email.setArgName("smtp/toMail");
      options.addOption(email);

      commandLine = parser.parse(options, args);
    }
    catch (UnrecognizedOptionException e) {
      System.out.println("Invalid argument.");
    }
    catch (MissingArgumentException e) {
      System.out.println("Missing Argument.  If applicable, argument will be a default.");
    }
  }

  /**
   * Boolean flag for using the -console argument.
   * @return true if in use
   */
  public boolean usingConsole() {
    return commandLine.hasOption(CONSOLE);
  }
  /**
   * Boolean flag for using the -uhm argument.
   * 
   * @return true if in use
   */
  public boolean usingUhm() {
    return commandLine.hasOption(UHM);
  }

  /**
   * Boolean flag for using the -hsl argument.
   * 
   * @return true if in use
   */
  public boolean usingHsl() {
    return commandLine.hasOption(HSL);
  }

  /**
   * Boolean flag for using the -within argument.
   * 
   * @return true if in use
   */
  public boolean usingWithin() {
    return commandLine.hasOption(WITHIN);
  }

  /**
   * Boolean flag for using the -wakeup argument.
   * 
   * @return true if in use
   */
  public boolean usingWakeup() {
    return commandLine.hasOption(WAKEUP);
  }

  /**
   * Boolean flag for using the -email argument.
   * 
   * @return true if in use
   */
  public boolean usingEmail() {
    return commandLine.hasOption(EMAIL);
  }

  /**
   * Obtains parameter: UH ID.
   * 
   * @return the ID as a string
   */
  public String getId() {
    String[] params = commandLine.getOptionValues(UHM);
    return params[0];
  }

  /**
   * Obtains parameter: user's last name.
   * 
   * @return user's last name as a string
   */
  public String getLastName() {
    String[] params = commandLine.getOptionValues(UHM);
    return params[1];
  }

  /**
   * Obtains parameter: barcode.
   * 
   * @return barcode as a string
   */
  public String getBarcode() {
    String[] params = commandLine.getOptionValues(HSL);
    return params[0];
  }

  /**
   * Obtains parameter: PIN.
   * 
   * @return PIN number as a string
   */
  public String getPin() {
    String[] params = commandLine.getOptionValues(HSL);
    return params[1];
  }

  /**
   * Obtains parameter: SMTP server.
   * 
   * @return server name as a string
   */
  public String getServer() {
    String[] params = commandLine.getOptionValues(EMAIL);
    return params[0];
  }

  /**
   * Obtains parameter: To address email.
   * 
   * @return email as a string
   */
  public String getToMail() {
    String[] params = commandLine.getOptionValues(EMAIL);
    return params[1];
  }

  /**
   * Obtains parameter for within argument.
   * 
   * @return an integer of the string argument
   */
  public int getDayInterval() {
    int interval = 0;
    try {
      String param = commandLine.getOptionValue(WITHIN);

      if (Integer.valueOf(param) >= (Integer.valueOf(0))) {
        interval = Integer.valueOf(param);
      }
    }
    catch (NumberFormatException e) {
      System.out.println("An integer was not entered.  Default '0' will be used.");
      return 0;
    }
    return interval;
  }

  /**
   * Obtains parameter for wakeup argument.
   * 
   * @return a double of the string argument
   */
  public double getTimeInterval() {
    double timeInterval = 0.00;

    try {
      String param = commandLine.getOptionValue(WAKEUP);
      timeInterval = Double.valueOf(param);
    }
    catch (NumberFormatException e) {
      System.out.println("A number was not entered.  Enter a number.");
    }
    return timeInterval;
  }
}
